<?php

  // Inputs:
  //
  // $terms: is an array of terms whose images should be found using Flickr's
  //         search api. The elements are ranked in descending order of
  //         relevance.
  // $search: the original search string requested by the user.
  // $photos_per_item: the number of photos to get per term.
  //
  // Outputs:
  //
  // The return value is an array whose elements are arrays which can be
  // indexed by "tag" and "url". The "tag" field holds the term that was used 
  // to make the search while the "url" field holds the image's url.
function get_images( $terms, $search, $photos_per_item = 1 ) {

  global $settings;

  // Return value
  $results = array();

  // Limit number of terms
  $n = 16;
  if( count( $terms ) > $n ) {
    $new_terms = array();

    for( $i = 0; $i < $n; $i++ )
      $new_terms[] = $terms[ $i ];

    $terms = $new_terms;
  }

  // An array of strings which are the HTTP requests that need to be made to
  // the Flickr API.
  $all_api_reqs = array();

  // Construct the appropriate URL (Flickr API call) for each of the terms.
  // Request up to 2 photos.
  // $all_api_reqs = make_all_rpc_urls( $terms, $search, $photos_per_item );

  foreach( $terms as $t )
    $all_api_reqs[] = make_rpc_url( $t[0], $search, $photos_per_item + 10 );

  // Get Flickr results by making parallel HTTP requests.
  $flickr_res = multiRequest( $all_api_reqs );
  
  // Iterate through each Flickr response, construct the URLs for the images,
  // and store in the return array.
  foreach( $flickr_res as $i => $f_res ) {

    // Request more photos than $photos_per_image
    $urls = get_img_urls( $f_res, $photos_per_item + 10);


    // An array of img URLs and web page URLs
    $f_urls = array();
    if( isset( $urls[0] ) )
      $f_urls = $urls[ 0 ];
    if( isset( $urls[1] ))
      $web_urls = $urls[ 1 ];
    if( isset( $urls[2] ))
      $f_urls_l = $urls[ 2 ];

    $f_urls_size = count( $f_urls );

    if( $f_urls_size <= 0 )
      continue;

    // An array to keep the limited number URLs returned by flickr.
    $f_l_urls = array();
    $l_web_urls = array();
    $f_l_urls_large = array();

    // Randomly pick up to $photos_per_item URLs
    for( $j = 0; $j < $photos_per_item; $j++ ) {

      $r = rand( 0, $f_urls_size - 1 );

      if( $f_urls[ $r ] == NULL )
	continue;

      $f_l_urls[] = $f_urls[ $r ];
      $l_web_urls[] = $web_urls[ $r ];
      $f_l_urls_large[] = $f_urls_l[ $r ];
      $f_urls[ $r ] = NULL;

    }
    
    foreach( $f_l_urls as $k => $img_url ) {

      $results[] = array( "tag" => $terms[ $i ][ 0 ],
			  "url" => $img_url ,
			  "web" => $l_web_urls[ $k ],
                          "context" => $terms[ $i ][1],
			  "url_l" => $f_l_urls_large[ $k ] );
    }
  }

  // --- Remove duplicates
  $dup_bkt = array();

  foreach( $results as $k => $r ) {
    
    if( isset($dup_bkt[ $r[ "url" ]]))
      unset( $results[$k] );
    else
      $dup_bkt[ $r[ "url" ]] = 1;

  }
  // ---

  return $results;

}

// This function takes as input an array of terms which need to be searched for
// using Flickr's API. The return value is an array of all the URLS needed to
// make the Flickr API call for each term. Return at most $n photos.
function make_all_rpc_urls( &$terms, $search, $n ) { 
  
  // Access Flickr API key.
  global $settings;

  // Return value.
  $result = array();

  foreach( $terms as $t)
    $result[] = "http://api.flickr.com/services/rest/".
                "?method=flickr.photos.search&api_key=".
                $settings[ "flickr_key" ] ."&".
                "sort=relevance&".
                "per_page=". $n ."&".
                "tags=". urlencode( $search ) ."&".
                "text=". urlencode($t);

    return $result;

}

/* Input:

   This function will create the HTTP URL request that can be used to query
   Flickr's API for relevant photos. The original search term $search is used
   to help improve the relevance of the photos that flickr returns. $n
   photos will be requsted from flickr for $term.

   $term: a term whose photo needs to be searched for.
   $search: original search string by the user
   $n: the number of photos per term that is desired.

   Return:

   An string that is the appropriate HTTP URL to query Flickr's API.
*/

function make_rpc_url( &$term, &$search, $n ) {
  
  global $settings;

  return "http://api.flickr.com/services/rest/".
         "?method=flickr.photos.search&api_key=".
         $settings[ "flickr_key" ] ."&".
         "extras=views&".
         "sort=relevance&".
         "per_page=". $n ."&".
         "tags=". urlencode( $search ) ."&".
         "text=". urlencode($term);
}

// Takes as input an array of URLS, $data, and returns the result for each
// page fetch in an array. 
// Source: http://www.phpied.com/simultaneuos-http-requests-in-php-with-curl/
function multiRequest($data, $options = array()) {

  // array of curl handles
  $curly = array();
  // data to be returned
  $result = array();

  // multi handle
  $mh = curl_multi_init();

  // loop through $data and create curl handles
  // then add them to the multi-handle
  foreach ($data as $id => $d) {

    $curly[$id] = curl_init();

    $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
    curl_setopt($curly[$id], CURLOPT_URL,            $url);
    curl_setopt($curly[$id], CURLOPT_HEADER,         0);
    curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);

    // post?
    if (is_array($d)) {
      if (!empty($d['post'])) {
        curl_setopt($curly[$id], CURLOPT_POST,       1);
        curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
      }
    }

    // extra options?
    if (!empty($options)) {
      curl_setopt_array($curly[$id], $options);
    }

    curl_multi_add_handle($mh, $curly[$id]);
  }

  // execute the handles
  $running = null;
  do {
    curl_multi_exec($mh, $running);
  } while($running > 0);

  // get content and remove handles
  foreach($curly as $id => $c) {
    $result[$id] = curl_multi_getcontent($c);
    curl_multi_remove_handle($mh, $c);
  }

  // all done
  curl_multi_close($mh);

  return $result;
}


// This function takes as input the XML returned by making an HTTP request
// to Flickr. This function constructs an array of two other arrays. The first
// array is a list of strings which are the URLs of the first $n images
// returned. The second is an array of strings which are the URLs to the Web
// page of the first $n images.
function get_img_urls( &$flickr_response, $n ) {

  // Return values.
  $urls = array();

  // Web page URLs
  $web = array();

  // Larger images
  $urls_z = array();

  // Used to limit the number of img URLs.
  $counter = 0;

  // Prase response
  $xml = new SimpleXMLElement( $flickr_response );

  // No photos in this response.
  if( count( $xml->children()->children() ) == 0 )
    return $urls;

  // Construct img URLS for up to $n result photos.
  foreach( $xml->children()->children() as $img ) {
    
    if( $counter >= $n )
      break;
    $counter++;

    $id = $img[ "id" ];
    $farm = $img[ "farm" ];
    $server = $img[ "server" ];
    $secret = $img[ "secret" ];
    $owner = $img[ "owner" ];

//     $web[] = "<a href=\"http://www.flickr.com/photos/". $owner ."/". $id .
//       "/\">pic 1</a>";
    $web[] = "http://www.flickr.com/photos/". $owner ."/". $id;

    $urls[] = "http://farm". $farm .".static.flickr.com/". $server .
              "/". $id ."_". $secret ."_m.jpg";

    $urls_z[] = "http://farm". $farm .".static.flickr.com/". $server .
              "/". $id ."_". $secret ."_z.jpg";

    
  }

  return array( $urls, $web, $urls_z );
}

